/**
 *
 *@Author:yangwenbo
 *@Date:2021/5/14 21:53
 ***/
const { execSQL } = require('./mysql'); // 数据库模块
const  connectHandle  = require('./affair')
const { SuccessModel, ErrorModel } = require('../model/responseModel'); // 返回格式统一
const bcrypt = require('bcrypt'); // 密码加密解密
const jwt = require('jsonwebtoken'); // 签发token  验证token
const { JWT_CONFIG } = require('../config/config') // token 配置
const svgCaptcha = require('svg-captcha'); // 验证码
const { encrypto, decrypt } = require('../model/password'); // 密码加密解密
const fs = require('fs'); // 系统文件模块
const path = require('path');

// __dirname 返回当前文件所在目录
// path.resolve 返回当前文件所在目录的父级 从右边到左边解析,如果遇到绝对路径直接返回
// console.log('__dirname',path.resolve(__dirname))
// 缓存
let session = {};
// 验证taoken
const verifyToken = (req, res, next) =>{
    // console.log('怎么事',req.headers.authorization )
    try{
        var token = req.headers.authorization.split(' ')[1];
    }catch(e){
        res.send({
            success: false,
            message: 'token无效'
        });
        return
    }
    // 验证token
    jwt.verify(token, JWT_CONFIG.secret, ( err, decoded) => {
        if ( err ) {
            // 返回错误信息
            res.send({
                success: false,
                message: 'token无效'
            });
            return
        }
    })
    next()
}




// 注册
const handleRegister = async ( req, res) => {
    const { pwd, username, codeValue } = req.body;
    if ( codeValue !== session.code) {
        res.status( 200 ).send(new ErrorModel(null, '验证码错误'));
        return
    }
    const salt = await bcrypt.genSalt(10); // 加盐 ,是系统随机生成的一个随机值，并且以随机的方式混在加密之后的密码中 多少位
    /*
    *  pwd: 前端传过来的密码要加密的数据
    *  salt: 用于哈西密码的盐, 如果指定为数字,则将使用指定的轮数生成盐并将其实用.推荐10(10粒大理盐)
    *  hashedPassword: 是加密过得密码
    *  输出:
    * 注意：每次调用输出都会不一样
    * */
    const hashedPassword = await bcrypt.hash(pwd, salt);
    const sql = `select username from client_user where username= '${username}'`;
    execSQL( sql ).then( result => {
        if ( result.length ) {
            res.status(200).send(new SuccessModel(result, '用户已存在'))
            return
        } else {
            // 不存在就插入数据库
            return execSQL(`insert into client_user (uid, username, pwd) values (0, '${username}', '${hashedPassword}')`);
        }
    }).then( data => {
        console.log('dta',data)
        res.status(200).send(new SuccessModel(null,'注册成功'))

    }).catch( err => {
        res.status( 500 ).send(new ErrorModel(err, '数据库错误'))
    });

}
// 验证码
const getCode = ( req, res ) => {
    if ( req.method === 'GET') {
        /*
       * ignoreChars:是过滤掉一些字符，例如0o1i
　　　　noise：干扰线个数
　　　　background:是图片背景颜色
　　　　color：字符颜色，如果background设置颜色，color为true
　　　　height:图片高度
       *
       * */
        const codeConfig = {
            size: 5,// 验证码长度
            ignoreChars: '0o1i', // 验证码字符中排除 0o1i
            noise: 2, // 干扰线条的数量
            height: 44
        }
        const captcha = svgCaptcha.create(codeConfig);
        session.code = captcha.text.toLowerCase(); //存session用于验证接口获取文字码
        const codeData = {
            img:captcha.data
        }
        res.send(codeData)
    }
}
// 登录
/**
 * @param { object } req - request 请求进来的东西都在这里
 * @param { object } res - 响应客户端的对象
 * @description:
 * @author: 文博
 * @date: 2021/5/18 15:23
 */
// const db = mysql.createPool({});
// db.query('select * from 表明 where', (result) => {})
const loginHandle = ( req, res ) => {
    if ( req.method = "post" ) {

        const { username, pwd } = req.body;
        // 另一种sql查询语句写法 "select * from user where username = ? and password = ?",[username,password]
        const sql = `select *  from client_user where username = '${username}' `;
        execSQL( sql ).then( result => {
            if ( result.length ) {
               /*
                * 校验 - 使用同步方法
               * bcrypt.compareSync 同步解密
               * pwd: 前端传过来的密码
               * result[0].pwd: 数据库查询出来的
               * isOk: 布尔值,为真时校验通过,登录成功
               * */
                const isOk =  bcrypt.compareSync(pwd, result[0].pwd);
                if ( isOk ) {
                    /*
                    * 签发token
                    * jwt.sign方法可生成token，第一个参数写的用户信息进去（可以写其他的），第二个是秘钥，第三个是过期时间
                    * */
                    const token = jwt.sign({
                            _id: 1 // 自定义字段
                        },
                        JWT_CONFIG.secret, // 加密token 校验token时要使用
                        {expiresIn: 3600 * 24 * 3}); // 过期时间
                    const data = {
                        token: token,
                        uid: result[0].uid
                    }
                    req.session.username = username; // 登录成功,设置session
                    res.cookie('username',username,{maxAge: 5* 60 *60}); // 登录成功,设置session
                    console.log('sss',req.cookies.username)

                    // res.cookie.username = username;
                    // res.redirect('/static/index.html');
                    res.status(200).send(new SuccessModel(data,'登录成功'))

                } else {
                    res.status(200).send(new ErrorModel(null,'密码错误'))
                }

                // res.redirect('/static/wwww/index.html')
            } else {
                res.status(200).send(new ErrorModel(null,'用户名或者密码不正确'))
            }
        }).catch( error => {
            console.log('error',error)
        });
    }
}
// 测试
const ceshi = ( req, res ) => {
    //  从authorization中获取token
    /*
    * token: token在headers头部 authorization 这个属性里 以Bearer 开头加空格 加token
    * */
    const token = req.headers.authorization.split(' ')[1];
    // 验证token
    jwt.verify(token, JWT_CONFIG.secret, ( err, decoded) => {
        if ( err ) {
            // 返回错误信息
            res.send({
                success: false,
                message: 'Failed to authenticate token. Make sure to include the ' +
                'token returned from /users call in the authorization header ' +
                ' as a Bearer token'
            });
            return
        }
    })
    res.send({
        name: 'index',
    })
}
// 上传图片
const uploadPictureHandle = ( req, res ) => {
    //
    const token = req.headers.authorization.split(' ')[1];
    if ( req.method === 'POST') {
        console.log('token',token)
        jwt.verify( token, JWT_CONFIG.secret, ( err, decoded) => {
            if ( err ) {
                // 返回错误信息
                res.send({
                    success: false,
                    message: '123'
                });
                return
            }

            const { originalname } = req.files[0];
            const oldPath =  './www/images/'+ req.files[0].filename
            const newPath = './www/images/'+originalname
            // console.log( req.files[0] )
            // console.log(oldPath)
            // console.log('aaa',newPath)
            fs.rename(oldPath,newPath,(err)=>{
                if ( err ) {
                    console.log(err)
                    return

                }
                // const sql = `insert into client_user(avatar) values(http://127.0.0.1:3000/static/images/'${originalname})`
                // execSQL(sql).then( result => {
                //     console.log('result',result)
                // })
                console.log(__dirname)
            })
            res.status(200).send({
                msg: 'laiab',
                status:1,
                data:'http://127.0.0.1:3000/static/images/'+originalname
            })
        });
    }
}
// 发表心情
const publishMood = ( req, res ) => {
    const { content } = req.query;
    if ( !content ) {
        res.status(200).send(new SuccessModel(null, '不能发表空心情'));
        return
    }
    const datatime = new Date().getTime()/1000;
    const sql = `insert into mood_table(id, content, datetime) values(0,'${content}',${datatime})`
    execSQL( sql ).then( result => {
        res.status(200).send(new SuccessModel(null, '发表成功'))
    }).catch( err => {
        if ( err ) {
            res.status(200).send(new ErrorModel(err, '发表失败'))
        }
    })
}
// 最新心情
const newMood = ( req, res ) => {
    const { content } = req.query;
    // if ( !content ) {
    //     res.status(200).send(new SuccessModel(null, '不能发表空心情'));
    //     return
    // }
    const sql = `select * from mood_table order by id desc`
    execSQL( sql ).then( result => {
        console.log('111',result[0])
        res.status(200).send(new SuccessModel(result[0], '查询成功'))
    }).catch( err => {
        if ( err ) {
            res.status(200).send(new ErrorModel(err, '查询失败'))
        }
    })
}
// 发布说说和博客
const publishHandle = ( req, res ) => {
   const { content, title, uid } = req.body;
   if (!content) {
       res.status(200).send(new ErrorModel(null, '不能为空'))
       return
   }
   let sql = ''
   if ( title ) {
        sql = `insert into blog_table(id,uid,blog_title, blog_content,state, like_no) values(0, ${uid}, '${title}', '${content}',0, 0)`
   } else  {
        sql = `insert into blog_table(id, uid, speak_content,state,like_no) values(0,${uid} '${content}',0,0)`
   }
   execSQL( sql ).then( result => {
       console.log("实时搜索",result)
       res.status(200).send(new SuccessModel(result,'发布成功'))
   }).catch( error => {
       res.status(500).send(new ErrorModel(null,error))
   })
}
// 获取博客列表
const getBlogList = ( req, res ) => {
    if ( req.method === "POST") {
        const { uid } = req.body;
        const  sql = `select * from blog_table where state = 1 order by id desc`;
        // 博客列表
        execSQL(sql).then( result => {
            req.result = result;
            let uidArr = []
            for ( let i = 0; i < req.result.length; i ++) {
                uidArr.push(req.result[i].uid);
            }
            const toRepeat = Array.from(new Set(uidArr))
            const sql2 = `select * from client_user where uid in (${toRepeat})`;
          //   用户
          return  execSQL( sql2 )
        }).then( userList => {
            if ( userList.length ) {
                // 获取点赞数量
                for ( let i = 0; i < req.result.length; i ++ ) {
                    // req.result[i] = {
                    //     avatar: item[0].avatar,
                    //     uid,
                    //     ...req.result[i]
                    // }
                    req.result[i].userinfo = userList.find( item => {
                        return item.uid === req.result[i].uid
                    });
                }
                res.status(200).send( new SuccessModel(req.result,'查询成功'))
            } else {
                res.status(500).send( new ErrorModel(null,'查询失败'))
            }
        }).catch( error => {
            console.log('error', error)
            res.status(500).send( new ErrorModel(null,'查询失败'))
        });
    }
}

// 管理后台获取博客列表
const adminBlogList = ( req, res ) => {
    if ( req.method === 'POST') {
        res.status(400).send(new ErrorModel('请求方式错误'))
        return
    }
    const sql = `select * from blog_table`
    execSQL(sql).then( rows => {
        // console.log('rows',rows)
        res.status(200).send(new SuccessModel(rows, '请求成功'))
    })
}
// 管理后台 审核操作
const approvedHandle = ( req, res ) => {

    if ( req.method === 'POST') {
        const { id, state } = req.body;
        const sql = `update blog_table set state = ${state} where id = ${id}`;
        execSQL(sql).then( rows => {
            if ( rows.affectedRows > 0 ) {
                res.status(200).send(new SuccessModel('更新成功'))
            }  else {
                res.status(500).send(new ErrorModel('更新失败'))
            }
        })
    }
}
// 后台审核不通过
const removeHandle = ( req, res ) => {
    // if ( req.method === 'OPTIONS') {
    //     console.log('快鱼')
    // }
    if ( req.method === 'POST' ) {
        const { id, state } = req.body;
        console.log('快鱼',req.body.id)
        const sql = `update blog_table set state = ${state} where id = ${id}`;
        execSQL(sql).then( rows =>{
            if ( rows.affectedRows > 0 ) {
                res.status(200).send(new SuccessModel('修改成功'))
            } else {
                res.status(500).send(rows, new ErrorModel('修改失败'))
            }
        })
    }
}
// 获取博客详情
// const getBlogDetails = ( req, res ) => {
//     console.log('req', req.query.id);
//     const { id } = req.query;
//     if ( !id ) {
//         res.status(500).send(new ErrorModel(null, 'id不能为空'));
//         return
//     }
//     const sql = `select * from blog_table where id = ${ id }`;
//     execSQL( sql ).then( result => {
//         res.status(200).send(new SuccessModel(result[0], '查询成功'))
//     })
// }

// 列表点赞
const handleLikeCount = ( req, res ) => {
    const { uid,  id, count } = req.query;
    // user_list_table
    console.log('uid',uid)
    const sql = `update blog_table set like_no = like_no+1 where uid=${uid}`
    // execSQL( sql ).then( result => {
    //     console.log('response',result)
    // })
    const updateHandle = async (vals) => {
        const connection = await connectHandle();
        connection.beginTransaction( err => {
            if ( err) {
                return '开启事务失败'
            } else {
                const sql = `update blog_table set like_no = like_no+1 where uid=${uid}`
                connection.query(sql, (e,rows, fields) => {
                    if ( e ) {
                         connection.rollback( ()=> {
                            console.log('更新失败数据回滚')
                            res.send(new ErrorModel(null, '更新失败数据回滚'))
                        })
                    } else {
                        connection.commit( error => {
                            if ( error ) {
                                console.log('事务提交失败')
                                res.send(new ErrorModel(null, '事务提交失败'))
                            }
                        });
                        connection.release() // 释放链接
                        res.send(new SuccessModel(rows, '成功'))
                        return { rows, success: true }
                    }
                })
            }
        })
    }

    updateHandle()
}
function publishMoment( req, res ) {
    const { content, id:blogid } = req.query;
    const sql = `update user_list_table set comment = '${content}' where blogid=${blogid}`
    execSQL(sql).then( value => {
        console.log('value',value)
        res.status(200).send(new SuccessModel(value,'评论成功'))
    }).catch( error => {
        console.log('error',error)
        res.status(500).send(new ErrorModel(null, '评论失败'))
    })
}

function getDate() {
    return  Date.now() / 1000
}
function toDou( n ) {
    return n < 10 ? '0'+ n : n;
}
// 解决跨域
function setCross( res ) {
    res.header("Access-Control-Allow-Credentials", "true")
    //设置允许跨域的域名，*代表允许任意域名跨域
    res.header("Access-Control-Allow-Origin","*");
    //允许的header类型
    res.header("Access-Control-Allow-Headers","content-type");
    //跨域允许的请求方式
    res.header("Access-Control-Allow-Methods","DELETE,PUT,POST,GET,OPTIONS");
    res.header('X-Powered-By', ' 3.2.1')
    res.header('Content-Type', 'application/json;charset=utf-8')

   // res.header("Access-Control-Allow-Origin", req.headers.origin); // 为了安全，可指定域名白名单，此处为所有域名都可访问，配置多个域名白名单不可直接写数组，要判断条件后赋值单个域名
    res.header("Access-Control-Allow-Headers", "X-Requested-With,Content-Type,token");
}
module.exports = {
    verifyToken,
    loginHandle,
    handleRegister,
    getCode,
    ceshi,
    uploadPictureHandle,
    publishMood,
    newMood,
    publishHandle,
    getBlogList,
    handleLikeCount,
    publishMoment,
    adminBlogList,
    approvedHandle,
    removeHandle
}